/*
    SUSAN® - Sole of Unix Save ANything

   Copyright (C) 2014-2020 Hechzh Property

   
*/
/*
 * Written by Marco van Wieringen, April 2014
 */
/**
 * @file
 * SUSAN Director -- User agent auditing.
 */

#include "include/susan.h"
#include "dird.h"
#include "dird/dird_globals.h"

namespace directordaemon {

/* Forward referenced functions */

/**
 * See if we need to audit this event.
 */
bool UaContext::AuditEventWanted(bool audit_event_enabled)
{
  if (!me->audit_events) { return audit_event_enabled; }

  if (audit_event_enabled) {
    const char* event = nullptr;

    foreach_alist (event, me->audit_events) {
      if (Bstrcasecmp(event, argk[0])) { return true; }
    }
  }

  return false;
}

/**
 * Log an audit event for a console that accesses an resource or cmd that is not
 * allowed.
 */
static inline void LogAuditEventAclMsg(UaContext* ua,
                                       const char* audit_msg,
                                       int acl,
                                       const char* item)
{
  const char* user_name;
  const char* host;
  const char* acl_type_name;

  user_name = (ua->user_acl)
                  ? ua->user_acl->corresponding_resource->resource_name_
                  : "default";
  host = (ua->UA_sock) ? ua->UA_sock->host() : "unknown";

  switch (acl) {
    case Job_ACL:
      acl_type_name = _("for Job");
      break;
    case Client_ACL:
      acl_type_name = _("for Client");
      break;
    case Storage_ACL:
      acl_type_name = _("for Storage");
      break;
    case Schedule_ACL:
      acl_type_name = _("for Schedule");
      break;
    case Pool_ACL:
      acl_type_name = _("for Pool");
      break;
    case Command_ACL:
      acl_type_name = _("for Command");
      break;
    case FileSet_ACL:
      acl_type_name = _("for Fileset");
      break;
    case Catalog_ACL:
      acl_type_name = _("for Catalog");
      break;
    case Where_ACL:
      acl_type_name = _("for Where restore location");
      break;
    case PluginOptions_ACL:
      acl_type_name = _("for Plugin Options");
      break;
    default:
      acl_type_name = "";
      break;
  }

  Emsg4(M_AUDIT, 0, audit_msg, user_name, host, acl_type_name, item);
}

void UaContext::LogAuditEventAclFailure(int acl, const char* item)
{
  if (!me->auditing) { return; }

  LogAuditEventAclMsg(
      this, _("Console [%s] from [%s], Audit acl failure %s %s\n"), acl, item);
}

void UaContext::LogAuditEventAclSuccess(int acl, const char* item)
{
  if (!me->auditing) { return; }

  LogAuditEventAclMsg(
      this, _("Console [%s] from [%s], Audit acl success %s %s\n"), acl, item);
}

/**
 * Log an audit event
 */
void UaContext::LogAuditEventCmdline()
{
  const char* user_name;
  const char* host;

  if (!me->auditing) { return; }

  user_name =
      user_acl ? user_acl->corresponding_resource->resource_name_ : "default";
  host = UA_sock ? UA_sock->host() : "unknown";

  Emsg3(M_AUDIT, 0, _("Console [%s] from [%s] cmdline %s\n"), user_name, host,
        cmd);
}

void UaContext::LogAuditEventInfoMsg(const char* fmt, ...)
{
  va_list arg_ptr;
  const char* user_name;
  const char* host;
  PoolMem message(PM_MESSAGE);

  if (!me->auditing) { return; }

  va_start(arg_ptr, fmt);
  message.Bvsprintf(fmt, arg_ptr);
  va_end(arg_ptr);

  user_name =
      user_acl ? user_acl->corresponding_resource->resource_name_ : "default";
  host = UA_sock ? UA_sock->host() : "unknown";

  Emsg3(M_AUDIT, 0, _("Console [%s] from [%s] info message %s\n"),
      user_name, host, message.c_str());
}

} /* namespace directordaemon */
